package main

import (
	"fmt"
	"reflect"
)

func main() {
	testImplementArith()
}

func testImplementArith() {
	m := Model2{}
	m.Num1 = 10
	m.Model.Num2 = 3
	m.Num2 = 5
	testOutput(&m)
	fmt.Println(m)
}

func testOutput(a interface{}) {
	if x, ok := a.(ArithI); ok {
		a1, a2 := x.GetNum()
		r := x.Add(a1, a2)
		fmt.Println(r)
		x.SetExtentKeyValue("Redundant", r)
	} else {
		panic("我不是正确的类型")
	}
}

type ArithI interface {
	Add(num1, num2 float64) float64
	Sub(num1, num2 float64) float64
	Mul(num1, num2 float64) float64
	Div(num1, num2 float64) float64
	GetNum() (float64, float64)
	SetExtentKeyValue(key string, value interface{})
}

type Model struct {
	Num1 float64
	Num2 float64
}

func (m Model) Add(n1, num2 float64) float64 {
	return n1 + num2
}
func (m Model) Sub(num1, num2 float64) float64 {
	return num1 + num2

}
func (m Model) Mul(num1, num2 float64) float64 {
	return num1 + num2

}
func (m Model) Div(num1, num2 float64) float64 {
	return num1 + num2
}
func (m Model) GetNum() (float64, float64) {
	return m.Num1, m.Num2
}

func (m *Model) SetExtentKeyValue(key string, value interface{}) {
	vStruct := reflect.ValueOf(m).Elem()
	x := vStruct.FieldByName(key)
	switch x.Kind() {
	case reflect.String:
		x.SetString(value.(string))
	case reflect.Int64:
		x.SetInt(value.(int64))
	case reflect.Float64:
		x.SetFloat(value.(float64))
	case reflect.Interface:
		fmt.Println("我该怎么办？")
	case reflect.Invalid:
		fmt.Println("这个字段不存在")
	default:
		fmt.Println(x.Kind())
	}
}

type Model2 struct {
	Model
	Num2      float64
	Redundant float64
}
